﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using BrightIdeasSoftware;
using WDTVHubGen.Base;

namespace WDTVHubGen.Util
{
    public static class  Utilities
    {
        // this will hold all of the utilities used by the 
        public static void SerializeObject(List<string> list, string fileName)
        {
            var serializer = new XmlSerializer(typeof (List<string>));
            using (var stream = File.OpenWrite(fileName))
            {
                serializer.Serialize(stream, list);
            }
        }

        // this will hold all of the utilities used by the 
        public static void SerializeObject(List<int> list, string fileName)
        {
            var serializer = new XmlSerializer(typeof(List<int>));
            using (var stream = File.OpenWrite(fileName))
            {
                serializer.Serialize(stream, list);
            }
        }


// And Deserialize

        public static void Deserialize(List<string> list, string fileName)
        {
            var serializer = new XmlSerializer(typeof (List<string>));
            using (var stream = File.OpenRead(fileName))
            {
                var other = (List<string>) (serializer.Deserialize(stream));
                list.Clear();
                list.AddRange(other);
            }
}

        public static void Deserialize(List<int> list, string fileName)
        {
            var serializer = new XmlSerializer(typeof (List<int>));
            using (var stream = File.OpenRead(fileName))
            {
                var other = (List<int>) (serializer.Deserialize(stream));
                list.Clear();
                foreach (int s in other)
                {
                    list.Add(s);
                }
                
            }
        }

        public static List<string> GetValidExtensions(string ve)
        {
            //if (options.VerboseErrors == Options.LoggingLevels.verbose) CLogger.WriteLog(ELogLevel.DEBUG, "In GetValidExtensions");
            //string ve = options.ValidExtensions;
            return ve.Split(',').ToList();
        }

    }
    public class MovieCardRenderer : AbstractRenderer
    {
        public override bool RenderItem(DrawListViewItemEventArgs e, Graphics g, Rectangle itemBounds, object rowObject)
        {
            // If we're in any other view than Tile, return false to say that we haven't done
            // the rendereing and the default process should do it's stuff
            ObjectListView olv = e.Item.ListView as ObjectListView;
            if (olv == null || olv.View != View.Tile)
                return false;

            // Use buffered graphics to kill flickers
            BufferedGraphics buffered = BufferedGraphicsManager.Current.Allocate(g, itemBounds);
            g = buffered.Graphics;
            g.Clear(olv.BackColor);
            g.SmoothingMode = ObjectListView.SmoothingMode;
            g.TextRenderingHint = ObjectListView.TextRenderingHint;

            if (e.Item.Selected)
            {
                this.BorderPen = Pens.Blue;
                this.HeaderBackBrush = new SolidBrush(olv.HighlightBackgroundColorOrDefault);
            }
            else
            {
                this.BorderPen = new Pen(Color.FromArgb(0x33, 0x33, 0x33));
                this.HeaderBackBrush = new SolidBrush(Color.FromArgb(0x33, 0x33, 0x33));
            }
            DrawMovieCard(g, itemBounds, rowObject, olv, (OLVListItem)e.Item);

            // Finally render the buffered graphics
            buffered.Render();
            buffered.Dispose();

            // Return true to say that we've handled the drawing
            return true;
        }

        internal Pen BorderPen = new Pen(Color.FromArgb(0x33, 0x33, 0x33));
        internal Brush TextBrush = new SolidBrush(Color.FromArgb(0x22, 0x22, 0x22));
        internal Brush HeaderTextBrush = Brushes.AliceBlue;
        internal Brush HeaderBackBrush = new SolidBrush(Color.FromArgb(0x33, 0x33, 0x33));
        internal Brush BackBrush = Brushes.LemonChiffon;

        public void DrawMovieCard(Graphics g, Rectangle itemBounds, object rowObject, ObjectListView olv, OLVListItem item)
        {
            const int spacing = 8;

            // Allow a border around the card
            itemBounds.Inflate(-2, -2);

            // Draw card background
            const int rounding = 20;
            GraphicsPath path = this.GetRoundedRect(itemBounds, rounding);
            g.FillPath(this.BackBrush, path);
            g.DrawPath(this.BorderPen, path);

            g.Clip = new Region(itemBounds);

            // Draw the photo
            Rectangle photoRect = itemBounds;
            photoRect.Inflate(-spacing, -spacing);

            VideoItem movie = rowObject as VideoItem;
            if (movie != null)
            {
                photoRect.Width = 75;
                string photoFile = movie.ThumbPath;
                //string photoFile = String.Format(@".\Photos\{0}.png", person.Photo);
                if (File.Exists(photoFile))
                {
                    Image photo =  Image.FromFile(photoFile);
                    photoRect.Height = ((int)(photo.Height * ((float)photoRect.Width / photo.Width)))-8;
                    g.DrawImage(photo, photoRect);
                }
                else
                {
                    g.DrawRectangle(Pens.DarkGray, photoRect);
                }
            }

            // Now draw the text portion
            RectangleF textBoxRect = photoRect;
            textBoxRect.X += (photoRect.Width + spacing);
            textBoxRect.Width = itemBounds.Right - textBoxRect.X - spacing;

            StringFormat fmt = new StringFormat(StringFormatFlags.NoWrap);
            StringFormat wrapfmt = new StringFormat();
            fmt.Trimming = StringTrimming.EllipsisCharacter;
            fmt.Alignment = StringAlignment.Center;
            fmt.LineAlignment = StringAlignment.Near;
            String txt = movie.Title == null ? movie.CleanFileName : movie.Title;

            using (Font font = new Font("Tahoma", 11))
            {
                // Measure the height of the title
                SizeF size = g.MeasureString(txt, font, (int)textBoxRect.Width, fmt);
                // Draw the title
                RectangleF r3 = textBoxRect;
                r3.Height = size.Height;
                path = this.GetRoundedRect(r3, 15);
                g.FillPath(this.HeaderBackBrush, path);
                g.DrawString(txt, font, this.HeaderTextBrush, textBoxRect, fmt);
                textBoxRect.Y += size.Height + spacing;
            }

            // Draw the other bits of information
            using (Font font = new Font("Tahoma", 8))
            {
                SizeF size = g.MeasureString("Wj", font, itemBounds.Width, fmt);

                fmt.Alignment = StringAlignment.Near;
                for (int i = 0; i < olv.Columns.Count; i++)
                {
                    OLVColumn column = olv.GetColumn(i);
                    if (column.IsTileViewColumn)
                    {
                        switch (column.AspectName)
                        {
                            case "Description":
                                if (movie.XmlPresent) txt = column.GetStringValue(rowObject);
                                else txt = string.Format("Cleaned File Name:{0}\n{1}", movie.CleanFileName, movie.FullFileName);
                                //SizeF sizef = g.MeasureString(txt, font, itemBounds.Width, wrapfmt);
                                SizeF sizef = TextRenderer.MeasureText(txt, font, itemBounds.Size, TextFormatFlags.WordBreak);
                                textBoxRect.Height = sizef.Height;
                                g.DrawString(txt, font, this.TextBrush, textBoxRect, wrapfmt);
                                textBoxRect.Y += sizef.Height;
                                break;
                            case "Season":
                            case "Episode":
                                if (movie.VideoType == VideoTypeEnum.MovieType) break;
                                if (!movie.XmlPresent)
                                {
                                    txt = string.Format("{0}: {1}", column.AspectName, column.GetStringValue(rowObject));
                                    textBoxRect.Height = size.Height;
                                    g.DrawString(txt, font, this.TextBrush, textBoxRect, fmt);
                                    textBoxRect.Y += size.Height;
                                }
                                break;
                            default:
                                if (movie.VideoType == VideoTypeEnum.MovieType) txt = column.GetStringValue(rowObject);
                                else txt = string.Format("{0}: {1}", column.AspectName, column.GetStringValue(rowObject));
                                textBoxRect.Height = size.Height;
                                g.DrawString(txt, font, this.TextBrush, textBoxRect, fmt);
                                textBoxRect.Y += size.Height;
                                break;
                        }
                    }
                }
            }
        }

        private GraphicsPath GetRoundedRect(RectangleF rect, float diameter)
        {
            GraphicsPath path = new GraphicsPath();

            RectangleF arc = new RectangleF(rect.X, rect.Y, diameter, diameter);
            path.AddArc(arc, 180, 90);
            arc.X = rect.Right - diameter;
            path.AddArc(arc, 270, 90);
            arc.Y = rect.Bottom - diameter;
            path.AddArc(arc, 0, 90);
            arc.X = rect.Left;
            path.AddArc(arc, 90, 90);
            path.CloseFigure();

            return path;
        }
    }
    /// <summary>
    /// This simple class just shows how an overlay can be drawn when the hot item changes.
    /// </summary>
    public class MovieCardOverlay : AbstractOverlay
    {
        public MovieCardOverlay()
        {
            MovieCardRenderer.HeaderBackBrush = Brushes.DarkBlue;
            MovieCardRenderer.BorderPen = new Pen(Color.DarkBlue, 2);
            this.Transparency = 255;
        }
        #region IOverlay Members

        public override void Draw(ObjectListView olv, Graphics g, Rectangle r)
        {
            if (olv.HotRowIndex < 0)
                return;

            if (olv.View == View.Tile)
                return;

            OLVListItem item = olv.GetItem(olv.HotRowIndex);
            if (item == null)
                return;

            Size cardSize = new Size(350, 120);
            Rectangle cardBounds = new Rectangle(
                r.Right - cardSize.Width - 8, r.Bottom - cardSize.Height - 8, cardSize.Width, cardSize.Height);
            MovieCardRenderer.DrawMovieCard(g, cardBounds, item.RowObject, olv, item);
        }

        #endregion

        private MovieCardRenderer MovieCardRenderer = new MovieCardRenderer();
    }

  /*  internal class TVCardRenderer : AbstractRenderer
    {
        public override bool RenderItem(DrawListViewItemEventArgs e, Graphics g, Rectangle itemBounds, object rowObject)
        {
            // If we're in any other view than Tile, return false to say that we haven't done
            // the rendereing and the default process should do it's stuff
            ObjectListView olv = e.Item.ListView as ObjectListView;
            if (olv == null || olv.View != View.Tile)
                return false;

            // Use buffered graphics to kill flickers
            BufferedGraphics buffered = BufferedGraphicsManager.Current.Allocate(g, itemBounds);
            g = buffered.Graphics;
            g.Clear(olv.BackColor);
            g.SmoothingMode = ObjectListView.SmoothingMode;
            g.TextRenderingHint = ObjectListView.TextRenderingHint;

            if (e.Item.Selected)
            {
                this.BorderPen = Pens.Blue;
                this.HeaderBackBrush = new SolidBrush(olv.HighlightBackgroundColorOrDefault);
            }
            else
            {
                this.BorderPen = new Pen(Color.FromArgb(0x33, 0x33, 0x33));
                this.HeaderBackBrush = new SolidBrush(Color.FromArgb(0x33, 0x33, 0x33));
            }
            DrawTVCard(g, itemBounds, rowObject, olv, (OLVListItem)e.Item);

            // Finally render the buffered graphics
            buffered.Render();
            buffered.Dispose();

            // Return true to say that we've handled the drawing
            return true;
        }

        internal Pen BorderPen = new Pen(Color.FromArgb(0x33, 0x33, 0x33));
        internal Brush TextBrush = new SolidBrush(Color.FromArgb(0x22, 0x22, 0x22));
        internal Brush HeaderTextBrush = Brushes.AliceBlue;
        internal Brush HeaderBackBrush = new SolidBrush(Color.FromArgb(0x33, 0x33, 0x33));
        internal Brush BackBrush = Brushes.LemonChiffon;

        public void DrawTVCard(Graphics g, Rectangle itemBounds, object rowObject, ObjectListView olv, OLVListItem item)
        {
            const int spacing = 8;

            // Allow a border around the card
            itemBounds.Inflate(-2, -2);

            // Draw card background
            const int rounding = 20;
            GraphicsPath path = this.GetRoundedRect(itemBounds, rounding);
            g.FillPath(this.BackBrush, path);
            g.DrawPath(this.BorderPen, path);

            g.Clip = new Region(itemBounds);

            // Draw the photo
            Rectangle photoRect = itemBounds;
            photoRect.Inflate(-spacing, -spacing);

            VideoItem movie = rowObject as VideoItem;
            if (movie != null)
            {
                photoRect.Width = 80;
                string photoFile = movie.ThumbPath;
                //string photoFile = String.Format(@".\Photos\{0}.png", person.Photo);
                if (File.Exists(photoFile))
                {
                    Image photo = Image.FromFile(photoFile);
                    if (photo.Width > photoRect.Width)
                        photoRect.Height = (int)(photo.Height * ((float)photoRect.Width / photo.Width));
                    else
                        photoRect.Height = photo.Height;
                    g.DrawImage(photo, photoRect);
                }
                else
                {
                    g.DrawRectangle(Pens.DarkGray, photoRect);
                }
            }

            // Now draw the text portion
            RectangleF textBoxRect = photoRect;
            textBoxRect.X += (photoRect.Width + spacing);
            textBoxRect.Width = itemBounds.Right - textBoxRect.X - spacing;

            StringFormat fmt = new StringFormat(StringFormatFlags.NoWrap);
            StringFormat wrapfmt = new StringFormat();
            fmt.Trimming = StringTrimming.EllipsisCharacter;
            fmt.Alignment = StringAlignment.Center;
            fmt.LineAlignment = StringAlignment.Near;
            String txt = movie.Title == null ? movie.CleanFileName : movie.Title;

            using (Font font = new Font("Tahoma", 11))
            {
                // Measure the height of the title
                SizeF size = g.MeasureString(txt, font, (int)textBoxRect.Width, fmt);
                // Draw the title
                RectangleF r3 = textBoxRect;
                r3.Height = size.Height;
                path = this.GetRoundedRect(r3, 15);
                g.FillPath(this.HeaderBackBrush, path);
                g.DrawString(txt, font, this.HeaderTextBrush, textBoxRect, fmt);
                textBoxRect.Y += size.Height + spacing;
            }

            // Draw the other bits of information
            using (Font font = new Font("Tahoma", 8))
            {
                SizeF size = g.MeasureString("Wj", font, itemBounds.Width, fmt);

                fmt.Alignment = StringAlignment.Near;
                for (int i = 0; i < olv.Columns.Count; i++)
                {
                    OLVColumn column = olv.GetColumn(i);
                    if (column.IsTileViewColumn)
                    {
                        if (column.AspectName == "Description")
                        {
                            if (movie.XmlPresent)
                                txt = column.GetStringValue(rowObject);
                            else txt = string.Format("Cleaned File Name:{0}\n{1}", movie.CleanFileName, movie.FullFileName);
                            //SizeF sizef = g.MeasureString(txt, font, itemBounds.Width, wrapfmt);
                            SizeF sizef = TextRenderer.MeasureText(txt, font, itemBounds.Size, TextFormatFlags.WordBreak);
                            textBoxRect.Height = sizef.Height;
                            g.DrawString(txt, font, this.TextBrush, textBoxRect, wrapfmt);
                            textBoxRect.Y += sizef.Height;
                        }
                        else
                        {
                            txt = string.Format("{0}: {1}", column.AspectName, column.GetStringValue(rowObject));
                            textBoxRect.Height = size.Height;
                            g.DrawString(txt, font, this.TextBrush, textBoxRect, fmt);
                            textBoxRect.Y += size.Height;
                        }
                    }
                }
            }
        }

        private GraphicsPath GetRoundedRect(RectangleF rect, float diameter)
        {
            GraphicsPath path = new GraphicsPath();

            RectangleF arc = new RectangleF(rect.X, rect.Y, diameter, diameter);
            path.AddArc(arc, 180, 90);
            arc.X = rect.Right - diameter;
            path.AddArc(arc, 270, 90);
            arc.Y = rect.Bottom - diameter;
            path.AddArc(arc, 0, 90);
            arc.X = rect.Left;
            path.AddArc(arc, 90, 90);
            path.CloseFigure();

            return path;
        }
    }
    /// <summary>
    /// This simple class just shows how an overlay can be drawn when the hot item changes.
    /// </summary>
    internal class TVCardOverlay : AbstractOverlay
    {
        public TVCardOverlay()
        {
            TVCardRenderer.HeaderBackBrush = Brushes.DarkBlue;
            TVCardRenderer.BorderPen = new Pen(Color.DarkBlue, 2);
            this.Transparency = 255;
        }
        #region IOverlay Members

        public override void Draw(ObjectListView olv, Graphics g, Rectangle r)
        {
            if (olv.HotRowIndex < 0)
                return;

            if (olv.View == View.Tile)
                return;

            OLVListItem item = olv.GetItem(olv.HotRowIndex);
            if (item == null)
                return;

            Size cardSize = new Size(250, 120);
            Rectangle cardBounds = new Rectangle(
                r.Right - cardSize.Width - 8, r.Bottom - cardSize.Height - 8, cardSize.Width, cardSize.Height);
            TVCardRenderer.DrawTVCard(g, cardBounds, item.RowObject, olv, item);
        }

        #endregion

        private TVCardRenderer TVCardRenderer = new TVCardRenderer();
    } */
}
